/**
 * 根据属性路径从对象中获取值
 * @param {object} row - 要获取属性的对象
 * @param {string} prop - 属性路径，可以是嵌套路径，如'user.name'
 * @param {any} defaultValue - 默认值，当属性不存在时返回该值
 * @returns {any} 获取到的属性值
 * @example
 * const user = { info: { name: '张三', age: 25 } };
 * const name = getProp(user, 'info.name'); // '张三'
 * const age = getProp(user, 'info.age'); // 25
 * const unknown = getProp(user, 'info.unknown'); // undefined
 */
export function getProp(row: object, prop: string, defaultValue: any = undefined): any {
  const propPath = prop.split('.');
  let value: any = row;
  for (const p of propPath) {
    value = value?.[p];
    if (value === undefined) break;
  }
  return value ?? defaultValue;
}

/**
 * 从对象中获取指定列表的属性，保持原对象的层级结构
 * @template T - 源对象类型
 * @param {T} source - 源对象
 * @param {string[]} props - 要获取的属性列表，可以包含嵌套路径，如'user.name'
 * @returns {Record<string, any>} 包含指定属性的新对象
 * @example
 * const user = { 
 *   id: 1, 
 *   info: { name: '张三', age: 25 },
 *   address: { city: '北京', district: '朝阳区' }
 * };
 * const result = pickProps(user, ['id', 'info.name', 'address.city']);
 * // 结果: { id: 1, info: { name: '张三' }, address: { city: '北京' } }
 */
export function pickProps<T extends object>(source: T, props: string[]): Record<string, any> {
  const result: Record<string, any> = {};

  props.forEach(prop => {
    const value = getProp(source, prop);

    // 只有当属性存在时才添加到结果对象中
    if (value !== undefined) {
      const propPath = prop.split('.');
      let current: Record<string, any> = result;

      // 处理嵌套路径，保持层级结构
      for (let i = 0; i < propPath.length - 1; i++) {
        const key = propPath[i];
        if (!current[key]) {
          current[key] = {};
        }
        current = current[key];
      }

      // 设置最终属性值
      current[propPath[propPath.length - 1]] = value;
    }
  });

  return result;
}

/**
 * 深度比较两个值是否相等
 * @param {any} a - 第一个值
 * @param {any} b - 第二个值
 * @returns {boolean} 如果两个值深度相等，返回true，否则返回false
 * @example
 * // 比较基本类型
 * deepEqual(5, 5); // 返回 true
 * deepEqual('hello', 'hello'); // 返回 true
 * 
 * // 比较对象
 * deepEqual({ id: 1, name: '张三' }, { id: 1, name: '张三' }); // 返回 true
 * deepEqual({ id: 1 }, { id: 2 }); // 返回 false
 * 
 * // 比较数组
 * deepEqual([1, 2, 3], [1, 2, 3]); // 返回 true
 * deepEqual([1, 2], [1, 2, 3]); // 返回 false
 */
export function deepEqual(a: any, b: any): boolean {
  // 如果两个值引用相同，直接返回true
  if (a === b) return true;

  // 处理null和undefined的情况
  if (a === null || b === null || a === undefined || b === undefined) {
    return a === b;
  }

  // 处理基本类型
  if (typeof a !== 'object' || typeof b !== 'object') {
    return a === b;
  }

  // 检查数组
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    return a.every((item, index) => deepEqual(item, b[index]));
  }

  // 检查对象
  if (typeof a === 'object' && typeof b === 'object') {
    const keysA = Object.keys(a);
    const keysB = Object.keys(b);

    if (keysA.length !== keysB.length) return false;

    return keysA.every(key => {
      if (!keysB.includes(key)) return false;
      return deepEqual(a[key], b[key]);
    });
  }

  // 其他情况返回false
  return false;
}